package EGS.impl;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;

import javax.swing.JTable;

import org.dom4j.Document;
import org.dom4j.Element;
import TOOLS.SQLtool;
import TOOLS.errCodeManagement;
import WORKPLACE.stationClient;

public class EGS_execute_service10000Impl{
	public boolean isUnknowCase = false;
	ExecutorService iExecutorService;
	Document MSG;
	boolean isPanel = false;
	stationClient iClient=null;
	SQLtool sql = null;
	static Map<String,String> ordersMap=new ConcurrentHashMap<>();
	/**
	 * 10000 申请条码
	 */
	public EGS_execute_service10000Impl(stationClient nClient, Document MSG_in, ExecutorService executorService, 
			SQLtool goldenSql) throws Exception {
		super();
		sql=goldenSql;
		if(nClient!=null) {
			iClient=nClient;
		}else {
			iClient=null;
		}
		MSG = MSG_in;
		iExecutorService = executorService;
	}

	public Document runCal() {
		String msgClass = "";
		try {
			if (MSG == null) {
				return null;
			}
			Element Mroot = MSG.getRootElement();
			msgClass = Mroot.element("header").attribute("messageClass").getValue();
			String iStation = Mroot.element("header").element("location").attribute("equipmentName").getValue();

			if (msgClass.equals("10000")) {// 申请条码
				iClient.orderActiveRequired = true;// 20210104修改为true，需要按工单确定工艺流程是否要求刻码
				String orderNo = null;
				try {
					orderNo = Mroot.element("body").element("PCBAssignReq").attribute("manufacturelotno").getValue();// iSN=modelNo
				} catch (Exception e) {
					;
				}
				if (orderNo == null) {
					orderNo = "";
				}
				if(orderNo.length()>0) {
					boolean flag=true;
					while(flag) {
						String oldThread=ordersMap.get(orderNo);
						while(oldThread!=null) {
							Thread.sleep(100);
							oldThread=ordersMap.get(orderNo);
						}
						String newThread=Thread.currentThread().getName();
						ordersMap.put(orderNo, newThread);
						Thread.sleep(100);
						oldThread=ordersMap.get(orderNo);
						flag=!oldThread.equals(newThread);//新旧线程名称一致则说明线程唯一，允许申请
						if(flag) {
							System.err.println("防重码生效");
						}
					}
				}

				Thread itt=null;//用于改变releaseFlag的子线程，防重码用
				Mroot.remove(Mroot.element("body"));
				Element eleB = Mroot.addElement("body");
				Element eleR = eleB.addElement("result");
				try {
					String strtt="select * from (\r\n" + 
							"select AAA.panelOrderNumber,AAA.orderIndex,AAA.planQty,AAA.addQty,count(1) as finishQty \r\n" + 
							"from (\r\n" + 
							"SELECT olp.panelOrderNumber,ol.orderIndex,ol.orderNumber,ol.planQty,ol.addQty,pS.isMarked \r\n" + 
							"FROM [dbo].[order_list_panel] olp \r\n" + 
							"LEFT JOIN [dbo].[order_list] ol ON ol.orderIndex=olp.orderIndex\r\n" + 
							"LEFT JOIN [dbo].[partStruct] pS ON pS.partIndex=ol.masterIndex \r\n" + 
							"where pS.isMarked=1 and olp.panelOrderNumber='"+orderNo+"' \r\n" + 
							"GROUP BY olp.panelOrderNumber,ol.orderIndex,ol.orderNumber,ol.planQty,ol.addQty,pS.isMarked \r\n" + 
							") AAA\r\n" + 
							"LEFT JOIN [dbo].[order_serialNumber] os ON os.orderIndex=AAA.orderIndex \r\n" + 
							"where os.releaseFlag=2\r\n" + 
							"GROUP BY AAA.panelOrderNumber,AAA.orderIndex,AAA.planQty,AAA.addQty\r\n" + 
							") BBB \r\n" + 
							"where finishQty>=(planQty+addQty) ";
					JTable t = sql.select(strtt);
					
					if(t!=null && t.getRowCount()>0) {//230719 addby Akite ：条码发行时小概率双线程同时发行导致同一工单同一时间发行两次
						throw new Exception("工单号" + orderNo + "条码申请失败,计划数量已达成");
					}
					strtt = "SELECT top 200 panelSN,pos,serialNumber FROM dbo.order_serialNumber "// 单表管控
							+ "where panelOrderNumber='" + orderNo + "' and releaseFlag=0 " + "ORDER BY panelSN,pos ";
					t = sql.select(strtt);
					
					if ((t == null) || (t.getRowCount() < 1)) {
						throw new Exception("工单号" + orderNo + "条码申请失败");
					} else {
						if ((iClient.activeOrderNumber == null) || (!iClient.activeOrderNumber.equals(orderNo))) {
//							sCl.changeStationOrder(orderNo, iiLayer);
							throw new Exception("工单号" + orderNo + "不是本工位当前激活工单");
						}
						int gmaxCounter=-1;
						String isttr="select ass.counter,ass.maxCounter,"
								+ "DATEDIFF(MINUTE, isnull(ass.lastCheck,getdate()), GETDATE()) as minuteLong,"
								+ "toli.timer,ass.lastCheck,getdate() as nowTime \r\n" + 
								"from [dbo].[assetStation] ass\r\n" + 
								"LEFT JOIN [QM].[timeOut_laserInspec] toli ON toli.timer is not null \r\n" + 
								"where ass.ID='"+iClient.myStationID+"' ";
						JTable t1=sql.select(isttr);
						if(t1!=null && t1.getRowCount()>0) {// counter>=maxCounter或当前时间超过巡检时间 报错
							int igCounter=Integer.parseInt(""+t1.getValueAt(0, 0));
							gmaxCounter=Integer.parseInt(""+t1.getValueAt(0, 1));
							if(gmaxCounter>0 && igCounter>=gmaxCounter) {
								throw new Exception("发码数量超过首检限制"+igCounter+"/"+gmaxCounter);
							}
							int igTlong=Integer.parseInt(""+t1.getValueAt(0, 2));
							int igMaxTlong=(int) Double.parseDouble(""+t1.getValueAt(0, 3));
							if(igMaxTlong>0 && igTlong>=igMaxTlong) {
								String igtl=""+t1.getValueAt(0, 4);
								String igmtl=""+t1.getValueAt(0, 5);
								throw new Exception("超过巡检时间限制"+igtl+"/"+igmtl+"("+igMaxTlong+")");
							}
						}
						String gPanelSN = (String) t.getValueAt(0, 0);
						if ((gPanelSN != null) && (gPanelSN.length() > 0)) {
							itt=new Thread(new Runnable() {
								String mPanelSN = gPanelSN;
								String iigStationID=iClient.myStationID;
								@Override
								public void run() {
									boolean flag = true;
									try {
										flag = true;
										while (flag) {
											try {
												sql.Command("update order_serialNumber set releaseFlag=1 "
														+ "where panelSN='" + mPanelSN + "'");
												flag = false;
											} catch (Exception e) {
												flag = true;// 如果sql连接失败，重试
												Thread.yield();
												try {
													Thread.sleep(300);
												} catch (InterruptedException e1) {
													;
												}
											}
										}
										
//										if(imaxCounter>0) {
//											sql.Command("insert [QM].[temp10000_laserInspec] (stationID,panelSN) "
//													+ "values ('"+iigStationID+"','"+mPanelSN+"') ");
//											sql.Command("update [dbo].[assetStation] set counter=counter+1 where ID='"+iigStationID+"' ");
//										}//2023-03-24 经过首检5拼后仍然需要周期性验证
										sql.Command("insert [QM].[temp10000_laserInspec] (stationID,panelSN) "
												+ "values ('"+iigStationID+"','"+mPanelSN+"') ");
										sql.Command("update [dbo].[assetStation] set counter=counter+1 where ID='"+iigStationID+"' ");
									} catch (Exception e2) {
										;
									}
//									try {
//										isql.close();
//									}catch(Exception e1) {
//										;
//									}

								}
							});
							itt.start();
							Element eleMP = eleB.addElement("PCBMPAssignAck");
							eleMP.addAttribute("barcode", gPanelSN);
							eleMP.addAttribute("manufacturelotno", orderNo);
//							eleMP.addAttribute("position", "0");
							for (int i = 0; i < t.getRowCount(); i++) {
								String iiPanelSN = (String) t.getValueAt(i, 0);
								if (gPanelSN.equals(iiPanelSN)) {
									String iiPos = (String) t.getValueAt(i, 1);
									String iiSN = (String) t.getValueAt(i, 2);
									Element eleSP = eleMP.addElement("PCBSPAssignAck");
									eleSP.addAttribute("barcode", iiSN);
									eleSP.addAttribute("position", iiPos);
								} else {
									eleMP.addAttribute("subpanelcount", "" + i);
									i = t.getRowCount() + 1;
								}
							}
						} else {
							throw new Exception("工单号" + orderNo + "申请条码失败,拼板条码不能为空");
						}
						// 获取第一拼，同时把它releaseFlag改成1，表示isRelease
					}
					eleR.addAttribute("errorCode", "0");
					eleR.addAttribute("errorText", "Valid");
					eleR.addAttribute("actionCode", "0");
					if(itt!=null) {
						try {
							itt.join();
						} catch (Exception e) {
							AKSLogs(100002, iStation + "_order=" + orderNo+"release=1子线程.join报错:"+e.getMessage());
						}
					}
					AKSLogs(100001, iStation + "_order=" + orderNo);
				} catch (Exception e) {
					String str = errCodeManagement.getErrText(e.getMessage());
					eleR.addAttribute("errorCode", "1");
					eleR.addAttribute("errorText", str);
					eleR.addAttribute("actionCode", "0");
					AKSLogs(100000, iStation + "_order=" + orderNo + ":_" + str);
				} finally{
					ordersMap.remove(orderNo);
				}
			} else {
				isUnknowCase = true;
				return null;
			}
			return MSG;
		} catch (Exception e) {
			if(iClient==null) {
				Element Mroot = MSG.getRootElement();
				Element eleR = Mroot.element("body").addElement("result");
				eleR.addAttribute("errorCode", "1");
				eleR.addAttribute("errorText", "工位信息获取失败");
				eleR.addAttribute("actionCode", "0");
				return MSG;
			}
			String str = errCodeManagement.getErrText(e.getMessage());
			System.out.println(str);
			return null;
		}

	}

	public void AKSLogs(int iType, String ilogClientNews) {
		SQLtool.AKSLogs(iType, ilogClientNews);
	}

	public static String GetTimestamp() {
		// "2017-12-10 15:52:10";
		String timestamp = new String();
		SimpleDateFormat t = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
		timestamp = "" + t.format(new Date());
		return timestamp;
	}

	public static long getDiffMS(String iStartT, String iEndT) {
		SimpleDateFormat t = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
		try {
			Date s = t.parse(iStartT);
			Date e = t.parse(iEndT);
			long diff = e.getTime() - s.getTime();
			if (diff < 0) {
				diff = diff * (-1);
			}
			return diff;
		} catch (ParseException e1) {
			e1.printStackTrace();
		}
		return -1;
	}
}
